// SmarTest Studio - UI控件树查看器

/**
 * UiViewer 类 - 管理UI控件树的显示和交互
 */
class UiViewer {
    constructor(options = {}) {
        // 配置选项
        this.options = {
            container: options.container || null,
            onNodeClick: options.onNodeClick || null,
            onNodeHover: options.onNodeHover || null,
            showNodeIds: options.showNodeIds !== false,
            expandByDefault: options.expandByDefault || false,
            ...options
        };
        
        // DOM元素
        this.container = this.options.container;
        
        // 当前UI树数据
        this.currentTreeData = null;
        
        // 初始化
        this.init();
    }
    
    /**
     * 初始化UI查看器
     */
    init() {
        if (!this.container) {
            console.warn('UiViewer: 未提供容器元素');
            return;
        }
        
        // 添加CSS类
        this.container.classList.add('ui-viewer-container');
    }
    
    /**
     * 渲染UI控件树
     * @param {Object} treeData - UI控件树数据
     */
    renderTree(treeData) {
        if (!treeData || !this.container) return;
        
        this.currentTreeData = treeData;
        
        // 清空容器
        this.container.innerHTML = '';
        
        // 创建树结构
        const treeHtml = this.createTreeHtml(treeData);
        this.container.innerHTML = treeHtml;
        
        // 添加交互功能
        this.addTreeInteractions();
    }
    
    /**
     * 显示加载状态
     */
    showLoading() {
        if (!this.container) return;
        
        this.container.innerHTML = `
            <div class="ui-viewer-loading">
                <div class="loading-indicator">
                    <i class="bi bi-arrow-repeat spin"></i> 正在加载控件树...
                </div>
            </div>
        `;
    }
    
    /**
     * 显示错误信息
     * @param {string} message - 错误消息
     */
    showError(message) {
        if (!this.container) return;
        
        this.container.innerHTML = `
            <div class="ui-viewer-error">
                <div class="alert alert-danger">
                    <i class="bi bi-exclamation-triangle me-2"></i>${message}
                </div>
            </div>
        `;
    }
    
    /**
     * 显示警告信息
     * @param {string} message - 警告消息
     */
    showWarning(message) {
        if (!this.container) return;
        
        this.container.innerHTML = `
            <div class="ui-viewer-warning">
                <div class="alert alert-warning">
                    <i class="bi bi-exclamation-triangle me-2"></i>${message}
                </div>
            </div>
        `;
    }
    
    /**
     * 显示空状态
     */
    showEmpty() {
        if (!this.container) return;
        
        this.container.innerHTML = `
            <div class="ui-viewer-empty">
                <div class="text-muted text-center p-4">
                    <i class="bi bi-grid-3x3 mb-2" style="font-size: 2rem;"></i>
                    <p>暂无UI控件树数据</p>
                </div>
            </div>
        `;
    }
    
    /**
     * 创建树HTML结构
     * @param {Object} node - 树节点数据
     * @param {number} level - 当前层级（用于缩进）
     * @returns {string} HTML字符串
     */
    createTreeHtml(node, level = 0) {
        if (!node) return '';
        
        let html = '';
        
        if (Array.isArray(node)) {
            // 如果是数组，遍历每个节点
            node.forEach(item => {
                html += this.createTreeHtml(item, level);
            });
        } else if (typeof node === 'object') {
            // 如果是对象，创建树节点
            const hasChildren = node.children && node.children.length > 0;
            const nodeType = node.type || 'unknown';
            const nodeId = node.id || '';
            const nodeText = node.text || nodeType;
            const nodeClass = node.className || '';
            const nodeResourceId = node.resourceId || '';
            
            // 创建节点HTML
            html += `<li class="tree-node" data-level="${level}" data-type="${nodeType}" data-id="${nodeId}" data-class="${nodeClass}" data-resource-id="${nodeResourceId}">`;
            
            // 添加折叠/展开图标（如果有子节点）
            if (hasChildren) {
                const expandedClass = this.options.expandByDefault ? '' : 'collapsed';
                const iconClass = this.options.expandByDefault ? 'bi-chevron-down' : 'bi-chevron-right';
                html += `<span class="tree-toggle"><i class="bi ${iconClass}"></i></span>`;
            } else {
                html += `<span class="tree-toggle-placeholder"></span>`;
            }
            
            // 添加节点图标和文本
            html += `<span class="tree-node-content">`;
            html += `<i class="bi bi-${this.getNodeIcon(nodeType)}"></i>`;
            html += `<span class="tree-node-text">${this.escapeHtml(nodeText)}</span>`;
            
            // 显示节点ID（如果启用且存在）
            if (this.options.showNodeIds && nodeId) {
                html += `<span class="tree-node-id">(${this.escapeHtml(nodeId)})</span>`;
            }
            
            // 显示节点类名（如果存在）
            if (nodeClass) {
                html += `<span class="tree-node-class">[${this.escapeHtml(nodeClass)}]</span>`;
            }
            
            html += `</span>`;
            
            // 添加子节点（如果有）
            if (hasChildren) {
                const childrenClass = this.options.expandByDefault ? 'tree-children' : 'tree-children collapsed';
                html += `<ul class="${childrenClass}">`;
                html += this.createTreeHtml(node.children, level + 1);
                html += `</ul>`;
            }
            
            html += `</li>`;
        }
        
        return html;
    }
    
    /**
     * 根据节点类型获取图标
     * @param {string} nodeType - 节点类型
     * @returns {string} 图标类名
     */
    getNodeIcon(nodeType) {
        const iconMap = {
            'window': 'window',
            'view': 'grid',
            'viewgroup': 'grid-3x3',
            'button': 'hand-index-thumb',
            'text': 'fonts',
            'textview': 'fonts',
            'input': 'input-cursor-text',
            'edittext': 'input-cursor-text',
            'image': 'image',
            'imageview': 'image',
            'checkbox': 'check-square',
            'radio': 'record-circle',
            'radiobutton': 'record-circle',
            'list': 'list-ul',
            'listview': 'list-ul',
            'recyclerview': 'list-ul',
            'scroll': 'arrows-move',
            'scrollview': 'arrows-move',
            'container': 'box',
            'layout': 'layout-three-columns',
            'linearlayout': 'layout-three-columns',
            'relativelayout': 'layout-three-columns',
            'framelayout': 'layout-three-columns',
            'constraintlayout': 'layout-three-columns',
            'toolbar': 'tools',
            'actionbar': 'tools',
            'menu': 'three-dots',
            'tab': 'folder',
            'switch': 'toggle-on',
            'seekbar': 'sliders',
            'progressbar': 'hourglass',
            'spinner': 'arrow-down-circle',
            'webview': 'globe'
        };
        
        // 尝试匹配完整类型名
        let icon = iconMap[nodeType.toLowerCase()];
        
        // 如果没有找到，尝试匹配部分类型名
        if (!icon) {
            const lowerType = nodeType.toLowerCase();
            for (const [key, value] of Object.entries(iconMap)) {
                if (lowerType.includes(key)) {
                    icon = value;
                    break;
                }
            }
        }
        
        return icon || 'question-circle';
    }
    
    /**
     * 添加树节点交互功能
     */
    addTreeInteractions() {
        if (!this.container) return;
        
        // 添加折叠/展开功能
        this.addToggleListeners();
        
        // 添加节点点击功能
        this.addNodeClickListeners();
        
        // 添加节点悬停功能
        this.addNodeHoverListeners();
    }
    
    /**
     * 添加折叠/展开监听器
     */
    addToggleListeners() {
        const toggles = this.container.querySelectorAll('.tree-toggle');
        
        toggles.forEach(toggle => {
            toggle.addEventListener('click', (e) => {
                e.stopPropagation();
                
                const node = toggle.closest('.tree-node');
                const children = node.querySelector('.tree-children');
                const icon = toggle.querySelector('i');
                
                if (children && icon) {
                    children.classList.toggle('collapsed');
                    
                    // 切换图标
                    if (children.classList.contains('collapsed')) {
                        icon.classList.remove('bi-chevron-down');
                        icon.classList.add('bi-chevron-right');
                    } else {
                        icon.classList.remove('bi-chevron-right');
                        icon.classList.add('bi-chevron-down');
                    }
                }
            });
        });
    }
    
    /**
     * 添加节点点击监听器
     */
    addNodeClickListeners() {
        if (!this.options.onNodeClick) return;
        
        const nodeContents = this.container.querySelectorAll('.tree-node-content');
        
        nodeContents.forEach(content => {
            content.addEventListener('click', (e) => {
                e.stopPropagation();
                
                const node = content.closest('.tree-node');
                const nodeData = this.extractNodeData(node);
                
                // 高亮选中的节点
                this.highlightNode(node);
                
                // 调用回调函数
                this.options.onNodeClick(nodeData, node);
            });
        });
    }
    
    /**
     * 添加节点悬停监听器
     */
    addNodeHoverListeners() {
        if (!this.options.onNodeHover) return;
        
        const nodeContents = this.container.querySelectorAll('.tree-node-content');
        
        nodeContents.forEach(content => {
            content.addEventListener('mouseenter', (e) => {
                const node = content.closest('.tree-node');
                const nodeData = this.extractNodeData(node);
                
                this.options.onNodeHover(nodeData, node, 'enter');
            });
            
            content.addEventListener('mouseleave', (e) => {
                const node = content.closest('.tree-node');
                const nodeData = this.extractNodeData(node);
                
                this.options.onNodeHover(nodeData, node, 'leave');
            });
        });
    }
    
    /**
     * 提取节点数据
     * @param {HTMLElement} nodeElement - 节点DOM元素
     * @returns {Object} 节点数据
     */
    extractNodeData(nodeElement) {
        return {
            type: nodeElement.dataset.type || '',
            id: nodeElement.dataset.id || '',
            className: nodeElement.dataset.class || '',
            resourceId: nodeElement.dataset.resourceId || '',
            level: parseInt(nodeElement.dataset.level) || 0,
            text: nodeElement.querySelector('.tree-node-text')?.textContent || ''
        };
    }
    
    /**
     * 高亮选中的节点
     * @param {HTMLElement} nodeElement - 要高亮的节点
     */
    highlightNode(nodeElement) {
        // 移除之前的高亮
        const previousHighlighted = this.container.querySelectorAll('.tree-node.highlighted');
        previousHighlighted.forEach(node => node.classList.remove('highlighted'));
        
        // 添加新的高亮
        nodeElement.classList.add('highlighted');
    }
    
    /**
     * 展开所有节点
     */
    expandAll() {
        if (!this.container) return;
        
        const collapsedChildren = this.container.querySelectorAll('.tree-children.collapsed');
        const collapsedIcons = this.container.querySelectorAll('.tree-toggle i.bi-chevron-right');
        
        collapsedChildren.forEach(children => {
            children.classList.remove('collapsed');
        });
        
        collapsedIcons.forEach(icon => {
            icon.classList.remove('bi-chevron-right');
            icon.classList.add('bi-chevron-down');
        });
    }
    
    /**
     * 折叠所有节点
     */
    collapseAll() {
        if (!this.container) return;
        
        const expandedChildren = this.container.querySelectorAll('.tree-children:not(.collapsed)');
        const expandedIcons = this.container.querySelectorAll('.tree-toggle i.bi-chevron-down');
        
        expandedChildren.forEach(children => {
            children.classList.add('collapsed');
        });
        
        expandedIcons.forEach(icon => {
            icon.classList.remove('bi-chevron-down');
            icon.classList.add('bi-chevron-right');
        });
    }
    
    /**
     * 搜索节点
     * @param {string} searchText - 搜索文本
     * @returns {Array} 匹配的节点元素数组
     */
    searchNodes(searchText) {
        if (!this.container || !searchText) return [];
        
        const searchLower = searchText.toLowerCase();
        const allNodes = this.container.querySelectorAll('.tree-node');
        const matchedNodes = [];
        
        // 清除之前的搜索高亮
        allNodes.forEach(node => {
            node.classList.remove('search-match', 'search-highlight');
        });
        
        // 搜索匹配的节点
        allNodes.forEach(node => {
            const nodeData = this.extractNodeData(node);
            const searchableText = [
                nodeData.text,
                nodeData.id,
                nodeData.className,
                nodeData.type
            ].join(' ').toLowerCase();
            
            if (searchableText.includes(searchLower)) {
                node.classList.add('search-match');
                matchedNodes.push(node);
                
                // 展开到匹配节点的路径
                this.expandToNode(node);
            }
        });
        
        return matchedNodes;
    }
    
    /**
     * 展开到指定节点的路径
     * @param {HTMLElement} targetNode - 目标节点
     */
    expandToNode(targetNode) {
        let currentNode = targetNode.parentElement;
        
        while (currentNode && currentNode !== this.container) {
            if (currentNode.classList.contains('tree-children')) {
                currentNode.classList.remove('collapsed');
                
                // 更新对应的图标
                const parentNode = currentNode.previousElementSibling;
                if (parentNode) {
                    const toggle = parentNode.querySelector('.tree-toggle i');
                    if (toggle) {
                        toggle.classList.remove('bi-chevron-right');
                        toggle.classList.add('bi-chevron-down');
                    }
                }
            }
            currentNode = currentNode.parentElement;
        }
    }
    
    /**
     * 获取模拟UI控件树数据
     * @returns {Object} 模拟UI控件树数据
     */
    getMockTreeData() {
        return {
            "type": "android.widget.FrameLayout",
            "id": "android:id/content",
            "className": "android.widget.FrameLayout",
            "children": [
                {
                    "type": "android.widget.LinearLayout",
                    "className": "android.widget.LinearLayout",
                    "children": [
                        {
                            "type": "android.widget.TextView",
                            "text": "Hello World",
                            "id": "com.example.app:id/text_hello",
                            "className": "android.widget.TextView"
                        },
                        {
                            "type": "android.widget.Button",
                            "text": "Click Me",
                            "id": "com.example.app:id/button_click",
                            "className": "android.widget.Button"
                        },
                        {
                            "type": "android.widget.EditText",
                            "text": "Enter text here",
                            "id": "com.example.app:id/edit_text",
                            "className": "android.widget.EditText"
                        }
                    ]
                }
            ]
        };
    }
    
    /**
     * 转义HTML字符
     * @param {string} text - 要转义的文本
     * @returns {string} 转义后的文本
     */
    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    /**
     * 清空查看器
     */
    clear() {
        if (this.container) {
            this.container.innerHTML = '';
        }
        this.currentTreeData = null;
    }
    
    /**
     * 初始化UI控件树刷新按钮
     * @param {Object} deviceSelector - 设备选择器实例
     */
    initRefreshButton(deviceSelector) {
        const refreshUiTreeBtn = document.querySelector('.refresh-ui-tree');
        if (refreshUiTreeBtn) {
            refreshUiTreeBtn.addEventListener('click', () => {
                const selectedDevice = deviceSelector ? deviceSelector.getCurrentDevice() : null;
                if (selectedDevice) {
                    deviceSelector.loadUiElementTree(selectedDevice);
                } else {
                    this.showWarning('请先选择设备');
                }
            });
        }
    }

    /**
     * 销毁查看器
     */
    destroy() {
        this.clear();
        this.container = null;
        this.options = null;
    }
}

// 导出类供其他模块使用
if (typeof module !== 'undefined' && module.exports) {
    module.exports = UiViewer;
}